﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace AppServices
{
	public class WCFService : IWCFService
	{
		#region Private fields
		private static readonly NORTHWNDEntities m_DATA_CONTEXT = DataContext.GetDataContext();
		#endregion

		public string GetData(int value)
		{
			return string.Format("You entered: {0}", value);
		}

		public CompositeType GetDataUsingDataContract(CompositeType composite)
		{
			if (composite.BoolValue)
			{
				composite.StringValue += "Suffix";
			}
			return composite;
		}

		#region Products
		public ProductsClass[] GetProducts()
		{
			List<ProductsClass> prodClass = new List<ProductsClass>();
			var prodList = m_DATA_CONTEXT.Products.ToList<Products>().OrderBy(param => param.ProductName);

			foreach( Products prod in prodList )
			{
				prodClass.Add(new ProductsClass(prod));
			}

			return prodClass.ToArray();
		}

		public void AddProduct(ProductsClass product)
		{
			Products pr = new Products
			{
				Discontinued = product.Discontinued,
				Logo = product.Logo,
				ProductName = product.ProductName,
				QuantityPerUnit = product.QuantityPerUnit,
				ReorderLevel = product.ReorderLevel,
				UnitPrice = product.UnitPrice,
				UnitsInStock = product.UnitsInStock,
				UnitsOnOrder = product.UnitsOnOrder
			};

			m_DATA_CONTEXT.AddToProducts(pr);
			m_DATA_CONTEXT.SaveChanges();

		}

		public void DeleteProduct(ProductsClass product)
		{
			var entity = (from en in m_DATA_CONTEXT.Products
						  where en.ProductName == product.ProductName
						  select en).FirstOrDefault();

			if (entity == null)
				return;

			var orders = (from o in m_DATA_CONTEXT.Orders
						  join od in m_DATA_CONTEXT.Order_Details on o.OrderID equals od.OrderID
						  join p in m_DATA_CONTEXT.Products on od.ProductID equals product.ProductID
						  where p.ProductName == product.ProductName
						  select o).ToList<Orders>();

			foreach (Orders o in orders)
			{
				DeleteOrder(new OrdersClass(o));
			}
			
			m_DATA_CONTEXT.DeleteObject(entity);			
			m_DATA_CONTEXT.SaveChanges();
		}

		public void EditProduct(ProductsClass product)
		{
			//ProductsClass pr = GetProductInfo(product.ProductID);
			
			//m_DATA_CONTEXT.Products.
		}

		public ProductsClass GetProduct(string productName)
		{
			var pr = (from p in m_DATA_CONTEXT.Products
					 where p.ProductName == productName
					 select p).FirstOrDefault();

			return new ProductsClass(pr);
		}

		public bool GetIfDuplicateProductNamesExists(string productName)
		{
			var dupl = from d in m_DATA_CONTEXT.Products
					   where d.ProductName == productName
					   select d;

			return dupl.Count() > 0;
		}

		public bool GetIfProductOrdersExists(string productName)
		{
			var result = from or in m_DATA_CONTEXT.ProductsOnOrder
						 where or.ProductName == productName
						 select or;

			return result.Count() > 0;
		}
		#endregion

		#region Customers
		public void AddCustomer(CustomersClass customer)
		{
			Customers c = new Customers
			{
				Address = customer.Address,
				CompanyName = customer.CompanyName,
				CustomerID = customer.CompanyName,
				ContactName = customer.ContactName,
				Phone = customer.Phone
			};

			m_DATA_CONTEXT.AddToCustomers(c);
			m_DATA_CONTEXT.SaveChanges();
		}

		public void DeleteCustomer(CustomersClass customer)
		{
 
		}

		public CustomersClass GetCustomer(string companyName)
		{
			var cust = (from c in m_DATA_CONTEXT.Customers
					   where c.CompanyName == companyName
					   select c).FirstOrDefault();

			return new CustomersClass(cust);
		}

		public CustomersClass[] GetCustomers()
		{
			List<CustomersClass> custClass = new List<CustomersClass>();
			var custList = m_DATA_CONTEXT.Customers.ToList<Customers>().OrderBy(param => param.CompanyName);

			foreach (Customers cust in custList)
			{
				custClass.Add(new CustomersClass(cust));
			}

			return custClass.ToArray();
		}
		
		public bool GetIfCustomerNamesExists(string customerName)
		{
			var dupl = from c in m_DATA_CONTEXT.Customers
					   where c.CompanyName == customerName
					   select c;

			return dupl.Count() > 0;
		}
		#endregion

		#region Orders
		public void AddOrder(OrdersClass order)
		{
			var cust = (from c in m_DATA_CONTEXT.Customers
						where c.CompanyName == order.Customer.CompanyName
						select c).FirstOrDefault();

			Orders ord = new Orders
			{
				Customers = cust,
				OrderDate = order.OrderDate,
				RequiredDate = order.RequiredDate,
				ShippedDate = order.ShippedDate,
				ShipVia = order.ShipVia,
				ShipName = order.ShipName,
				ShipAddress = order.ShipAddress,
				Freight = order.Freight
			};

			m_DATA_CONTEXT.AddToOrders(ord);
			m_DATA_CONTEXT.SaveChanges();
		}

		public void DeleteOrder(OrdersClass ord)
		{
			var order = (from en in m_DATA_CONTEXT.Orders
						  where en.OrderID == ord.OrderID
						  select en).FirstOrDefault();

			if (order == null)
				return;

			var ordDetails = from od in m_DATA_CONTEXT.Order_Details
							 where od.OrderID == order.OrderID
							 select od;

			foreach( var od in ordDetails )
			{
				m_DATA_CONTEXT.DeleteObject(od);
			}

			var customers = from o in m_DATA_CONTEXT.Orders
							where o.Customers.CustomerID == order.Customers.CustomerID
							select o.Customers;
			
			if(customers.Count() == 1)
			{
				m_DATA_CONTEXT.DeleteObject(customers.First());
			}

			m_DATA_CONTEXT.DeleteObject(order);			
			m_DATA_CONTEXT.SaveChanges();
		}

		public OrdersClass GetOrder(OrdersClass order)
		{
			var ord = (from o in m_DATA_CONTEXT.Orders
					   where o.Customers.CompanyName == order.Customer.CompanyName &&
							o.OrderDate == order.OrderDate &&
							o.RequiredDate == order.RequiredDate &&
							o.ShippedDate == order.ShippedDate &&
							o.ShipVia == order.ShipVia &&
							o.ShipName == order.ShipName &&
							o.ShipAddress == order.ShipAddress &&
							o.Freight == order.Freight
					  select o).FirstOrDefault();

			return new OrdersClass(ord);
		}

		public OrdersClass GetOrder(int orderID)
		{
			var ord = (from o in m_DATA_CONTEXT.Orders
					   where o.OrderID == orderID
					   select o).FirstOrDefault();

			return new OrdersClass(ord);
		}

		public OrdersClass[] GetOrders()
		{
			List<OrdersClass> orderClass = new List<OrdersClass>();
			var orderList = m_DATA_CONTEXT.Orders.ToList<Orders>().OrderBy(param => param.OrderID);
	
			foreach (Orders order in orderList)
			{
				orderClass.Add(new OrdersClass(order));
			}

			return orderClass.ToArray();
		}

		#endregion

		#region Order Details
		public void AddOrderDetails(OrderDetailsClass orderDetails)
		{
			var dbOrder = (from o in m_DATA_CONTEXT.Orders
							where o.OrderID == orderDetails.Order.OrderID
							select o).FirstOrDefault();

			var dbProduct = (from p in m_DATA_CONTEXT.Products
						   where p.ProductName == orderDetails.Product.ProductName
						   select p).FirstOrDefault();

			Order_Details ordD = new Order_Details
			{
				Orders = dbOrder,
				Products = dbProduct,
				OrderID = dbOrder.OrderID,
				ProductID = dbProduct.ProductID,
				UnitPrice = dbProduct.UnitPrice.Value,
				Quantity = orderDetails.Quantity,
				Discount = orderDetails.Discount
			};

			m_DATA_CONTEXT.AddToOrder_Details(ordD);
			m_DATA_CONTEXT.SaveChanges();
		}

		public void DeleteOrderDetails(OrderDetailsClass orderDetails)
		{
			var od = (from o in m_DATA_CONTEXT.Order_Details
					  where o.OrderID == orderDetails.Order.OrderID
					  select o).FirstOrDefault();

			//m_DATA_CONTEXT.DeleteObject(od);
			m_DATA_CONTEXT.SaveChanges();
		}

		public OrderDetailsClass GetOrderDetails(int orderID)
		{
			var od = (from o in m_DATA_CONTEXT.Order_Details
					  where o.OrderID == orderID
					  select o).FirstOrDefault();

			return new OrderDetailsClass(od);
		}
		#endregion

		#region ProductsOnOrderFullInfo

		public void AddProductsOnOrderFullInfo(ProductsOnOrderFullInfoClass orderDetails)
		{
			ProductsOnOrderFullInfo info = new ProductsOnOrderFullInfo
			{

			};

			m_DATA_CONTEXT.AddToProductsOnOrderFullInfo(info);
			m_DATA_CONTEXT.SaveChanges();
		}

		public void DeleteProductsOnOrderFullInfo(ProductsOnOrderFullInfoClass orderDetails)
		{

		}

		public ProductsOnOrderFullInfoClass[] GetProductsOnOrderFullInfo()
		{
			List<ProductsOnOrderFullInfoClass> pClass = new List<ProductsOnOrderFullInfoClass>();
			var pList = m_DATA_CONTEXT.ProductsOnOrderFullInfo.ToList<ProductsOnOrderFullInfo>().OrderBy(param => param.ProductName);

			foreach (ProductsOnOrderFullInfo p in pList)
			{
				pClass.Add(new ProductsOnOrderFullInfoClass(p));
			}

			return pClass.ToArray();
		}

		#endregion
	}
}
